package xyz.xtt.exchange.service.impl;

import java.util.Objects;
import java.util.Optional;

import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import xyz.xtt.common.asset.AssertUtils;
import xyz.xtt.common.starter.cache.CacheManager;
import xyz.xtt.exchange.constants.ErrorMessage;
import xyz.xtt.exchange.constants.ExchangeCache;
import xyz.xtt.exchange.entity.TblAssetUserConfig;
import xyz.xtt.exchange.mapper.TblAssetUserConfigMapper;
import xyz.xtt.exchange.service.ITblAssetUserConfigService;

/**
 * <p>
 * 资产用户设置表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-02-18
 */
@Slf4j
@Service
public class TblAssetUserConfigServiceImpl extends ServiceImpl<TblAssetUserConfigMapper, TblAssetUserConfig> implements ITblAssetUserConfigService {
	@Autowired
	private CacheManager cacheManager;

	@Override
	public TblAssetUserConfig infoConfig(Long userId, Long assetId) {
		LambdaQueryChainWrapper<TblAssetUserConfig> query = new LambdaQueryChainWrapper<>(baseMapper);
		TblAssetUserConfig config = query.eq(TblAssetUserConfig::getAssetId, assetId).eq(TblAssetUserConfig::getUid, userId).one();
		return config;
	}

	@Override
	public boolean saveOrUpdateConfig(TblAssetUserConfig newConfig) {
		LambdaQueryChainWrapper<TblAssetUserConfig> query = new LambdaQueryChainWrapper<>(baseMapper);
		Optional<TblAssetUserConfig> oneOpt = query
				.eq(TblAssetUserConfig::getAssetId, newConfig.getAssetId())
				.eq(TblAssetUserConfig::getUid, newConfig.getUid())
				.oneOpt();
		oneOpt.ifPresentOrElse(x -> updateConfig(x, newConfig), () -> this.saveConfig(newConfig));
		return true;
	}

	@Override
	public boolean saveConfig(TblAssetUserConfig newConfig) {
		// 保存的时候必须有公示期
		if (newConfig.checkPublicityPeriodIsNull()) {
			log.info("saveConfig checkPublicityPeriod is null assetId:{}", newConfig.getAssetId());
			AssertUtils.isTrue(true, ErrorMessage.NOTICE_PERIOD_EX);
		}
		boolean save = this.save(newConfig);
		AssertUtils.isFalse(save, ErrorMessage.ASSET_SETTING_EX);
		return save;
	}

	@Override
	public boolean updateConfig(TblAssetUserConfig assetUserConfig, TblAssetUserConfig newConfig) {
		// 更新时，如果 publicityPeriodResult
		LambdaUpdateChainWrapper<TblAssetUserConfig> update = new LambdaUpdateChainWrapper<>(baseMapper);
		if (assetUserConfig.checkPublicityPeriodIsNull() && newConfig.checkPublicityPeriodIsNull()) {
			log.info("updateConfig old and new both null assetId:{}", newConfig.getAssetId());
			AssertUtils.isTrue(false, ErrorMessage.ASSET_SETTING_EX);
		}
		Long publicityPeriodStart = newConfig.getPublicityPeriodStart();
		Long publicityPeriodEnd = newConfig.getPublicityPeriodEnd();
		// 如果忆有的公示期不是公的,本次更新操作不处理公示期
		if (!assetUserConfig.checkPublicityPeriodIsNull()) {
			publicityPeriodStart = null;
			publicityPeriodEnd = null;
		}
		boolean result = update
				.eq(TblAssetUserConfig::getAssetId, assetUserConfig.getAssetId())
				.eq(TblAssetUserConfig::getUid, assetUserConfig.getUid())
				.set(Objects.nonNull(publicityPeriodStart), TblAssetUserConfig::getPublicityPeriodStart, publicityPeriodStart)
				.set(Objects.nonNull(publicityPeriodEnd), TblAssetUserConfig::getPublicityPeriodEnd, publicityPeriodEnd)
				.set(TblAssetUserConfig::getDiscount, assetUserConfig.getDiscount())
				.set(TblAssetUserConfig::getPreSellStart, assetUserConfig.getPreSellStart())
				.set(TblAssetUserConfig::getPreSellEnd, assetUserConfig.getPreSellEnd())
				.set(TblAssetUserConfig::getUptTime, LocalDateTime.now())
				.update();
		if (result) {
			cacheManager.delete(ExchangeCache.TBL_ASSET_USER_CONFIG, String.valueOf(assetUserConfig.getUid()), String.valueOf(assetUserConfig.getAssetId()));
		}
		return result;
	}

	@Override
	public TblAssetUserConfig infoConfigWithCache(Long userId, Long assetId) {
		return cacheManager.cacheObj(() -> infoConfig(userId, assetId), ExchangeCache.TBL_ASSET_USER_CONFIG, String.valueOf(userId), String.valueOf(assetId));
	}

	@Override
	public boolean updateConfigPublicityPeriod(Long userId, Long assetId) {
		LambdaUpdateChainWrapper<TblAssetUserConfig> update = new LambdaUpdateChainWrapper<>(baseMapper);
		return update
				.eq(TblAssetUserConfig::getAssetId, assetId)
				.eq(TblAssetUserConfig::getUid, userId)
				.set(TblAssetUserConfig::getPublicityPeriodStart, null)
				.set(TblAssetUserConfig::getPublicityPeriodEnd, null)
				.set(TblAssetUserConfig::getPublicityPeriodResult, 1)
				.isNotNull(TblAssetUserConfig::getPublicityPeriodStart)
				.isNotNull(TblAssetUserConfig::getPublicityPeriodEnd)
				.update();
	}

	@Override
	public TblAssetUserConfig getByAssetId(long assetId) {
		LambdaQueryChainWrapper<TblAssetUserConfig> query = new LambdaQueryChainWrapper<>(baseMapper);
		return query.eq(TblAssetUserConfig::getAssetId, assetId).eq(TblAssetUserConfig::getIsDel, false).one();
	}
}
